package com.weme.live.view

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Path.Direction
import android.graphics.PathMeasure
import android.util.AttributeSet
import android.view.View
import android.view.animation.LinearInterpolator


/**
 * @author wuyr
 * @github https://github.com/wuyr/
 * @since 2024-02-19 下午5:20
 */
class LastTimeView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : View(context, attrs, defStyleAttr) {

    /**
     * 圆角
     */
    var radius = 8F

    /**
     * 线条颜色
     */
    var lineColor = Color.YELLOW

    /**
     * 线条宽度
     */
    var lineWidth = 10F

    /**
     * 时长(秒)
     */
    var duration = 30


    private val paint = Paint(Paint.ANTI_ALIAS_FLAG or Paint.DITHER_FLAG).apply {
        strokeCap = Paint.Cap.ROUND
        textAlign = Paint.Align.CENTER
    }

    private val path = Path()
    private var pathPoints = FloatArray(0)

    fun prepare() {
        post {

            pathPoints = decomposePath(path.apply {
                reset()
                addRoundRect(lineWidth / 2F, lineWidth / 2F, width - lineWidth, height - lineWidth, radius, radius, Direction.CCW)
            })
            currentTextValue = "${duration}s"
            currentProgress = -1F
            invalidate()
        }
    }

    private var currentProgress = 0F
    private var currentTextValue = "0s"
    private var lastAnimator: ValueAnimator? = null

    fun start() {
        lastAnimator?.cancel()
        post {
            ValueAnimator.ofFloat(0F, 1F).setDuration(duration * 1000L).apply {
                lastAnimator = this
                interpolator = LinearInterpolator()
                addUpdateListener {
                    currentProgress = it.animatedFraction
                    currentTextValue = "${if (currentProgress == 1F) "0" else (this@LastTimeView.duration * (1F - currentProgress) + 1).toInt().toString()}s"
                    postInvalidate()
                }
            }.start()
        }
    }

    override fun onDraw(canvas: Canvas) {
        if (pathPoints.isEmpty()) return
//        paint.textSize = resources.getDimension(com.example.resources.R.dimen.sp_30)
//        canvas.drawText(currentTextValue, width / 2F, (height - paint.fontMetricsInt.run { bottom + top }) / 2F, paint)
        paint.apply {
            color = lineColor
            style = Paint.Style.STROKE
            strokeWidth = lineWidth
        }
        when (currentProgress) {
            -1F -> canvas.drawPath(path, paint)
            0F -> return
            else -> for (i in pathPoints.indices step 2) {
                val fraction = i.toFloat() / pathPoints.size
                if (fraction > currentProgress) {
                    canvas.drawPoint(pathPoints[i], pathPoints[i + 1], paint)
                }
            }
        }
    }

    private fun decomposePath(path: Path, precision: Int = 1): FloatArray {
        if (precision <= 0) {
            throw IllegalArgumentException("precision must be > 0")
        }
        if (path.isEmpty) {
            return FloatArray(0)
        }
        val pathMeasure = PathMeasure(path, false)
        val pathLength = pathMeasure.length
        val numPoints = (pathLength / precision).toInt() + 1
        val points = FloatArray(numPoints * 2)
        val position = FloatArray(2)
        var index = 0
        var distance: Float
        for (i in 0 until numPoints) {
            distance = i * pathLength / (numPoints - 1)
            pathMeasure.getPosTan(distance, position, null)
            points[index] = position[0]
            points[index + 1] = position[1]
            index += 2
        }
        return points
    }
}